package Syntaxe;

import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.Map;

import data.DataReader;

public class Program {
	public String filename;
	public static StringBuffer lireResult;
	public static DataReader data;
	public static Map<String, Fraction> list = new HashMap<String, Fraction>();
	// TODO
	public LinkedHashSet<String> SetVar;
	public int numVar;

	Invariant inVarReel = new Invariant(new LinkedList<Expression>());
	Invariant inVarVisuel = new Invariant(new LinkedList<Expression>());
	StringBuffer lireText = new StringBuffer();
	StringBuffer realText = new StringBuffer();
	int pointeurGlobalHead = 0;

	//
	public Program(String name) {
		filename = name;
		data = new DataReader(filename);
	}

	public void lireDeclaration() {
		lireResult = new StringBuffer(data.nextData());
		lireText.append(lireResult);
		realText.append(lireResult);
		pointeurGlobalHead = lireResult.length();

		// Enregistrer les variables:
		int i = lireResult.indexOf(":") + 1;
		while (i < lireResult.length()) {
			if (lireResult.charAt(i) == ' ')
				i++;
			if (lireResult.charAt(i) == '.')
				break;
			int start = i;
			int end = i;
			while ((lireResult.charAt(end + 1) != ',')
					&& (lireResult.charAt(end + 1) != '.')
					&& (lireResult.charAt(end + 1) != ' '))
				end++;
			String var = lireResult.substring(start, end + 1);
			list.put(var, new Fraction(0));
			i = end + 2;
		}

		// Afficher les variables enregistr��s.
		for (String test : list.keySet()) {
			System.out.println(test);
		}
		// get the dict of vars
		SetVar.addAll(list.keySet());
		numVar = SetVar.size();

	}

	public void lireBlock(StringBuffer strBufferText) {
		if (pointeurGlobalHead >= lireText.length())
			return;

		int i = 0;
		int start = i;
		int modifier = 0;
		StringBuffer textCurrent = strBufferText;

		// Lire l'invariant qui se trouve au d��but du block qui est en train
		// d'��tre lu.
		System.out.println(lireText.charAt(pointeurGlobalHead));
		System.out.println("Hello");
		int end = textCurrent.indexOf("}");
		System.out.println(end);
		String inVarCurrent = textCurrent.substring(start, end + 1);
		StringBuffer inVarCurrentVisuel = new StringBuffer(inVarCurrent);
		System.out.println(inVarCurrentVisuel);
		System.out.println(pointeurGlobalHead);
		System.out.println("��ʼ��invariant");
		lireInvariant(inVarCurrentVisuel); // ������
		System.out.println("invariant����");
		// condition pour v��rifier est-ce qu'on a d��j�� fini de lire le
		// programme.
		pointeurGlobalHead += end + 1;
		if (pointeurGlobalHead >= lireText.length()) {
			System.out.println("����Program��");
			return;
		}
		modifier = end + 1;
		while (textCurrent.charAt(modifier) == ' '
				&& modifier < textCurrent.length() - 1)
			modifier++;
		if (modifier == textCurrent.length() - 1)
			return;

		// Si on n'avait pas fini de lire ce block, on devrais ensuite lire
		// l'instruction suivante.
		if (textCurrent.charAt(modifier) != '}') {
			int start1 = end + 1;
			while (textCurrent.charAt(start1) == ' ')
				start1++;
			System.out.println(pointeurGlobalHead);

			// condition 1, dans ce cas, on lire l'instruction "if ".
			if (textCurrent.charAt(start1) == 'i'
					&& textCurrent.charAt(start1 + 1) == 'f') {

				System.out.println("��ʼ��if��instruction");
				lireInstructionIf(
						new StringBuffer(lireText.substring(
								pointeurGlobalHead,
								pointeurGlobalHead
										+ longeurDeIf(lireText,
												pointeurGlobalHead))),
						pointeurGlobalHead
								+ longeurDeIf(lireText, pointeurGlobalHead));
				System.out.println("����if��instruction");

				// pointeurGlobalHead+=longeurDeIf(lireText,pointeurGlobalHead);

				// Apr��s avoir fini lecture de instruction if , on na d��j��
				// ��pluch�� le premier niveau de ce block,
				// il nous reste �� lire son fils
				int tryeur = pointeurGlobalHead + 1;
				while (lireText.charAt(tryeur) == ' ') {
					pointeurGlobalHead++;
					tryeur++;
				}
				pointeurGlobalHead += 1;
				lireBlock(new StringBuffer(
						lireText.substring(pointeurGlobalHead)));
				System.out.println(lireText.substring(pointeurGlobalHead));
			}

			// condition 2,dans ce cas, on devoit lire l'instruction "while ".
			if (textCurrent.charAt(start1) == 'w'
					&& textCurrent.charAt(start1 + 1) == 'h'
					&& textCurrent.charAt(start1 + 2) == 'i'
					&& textCurrent.charAt(start1 + 3) == 'l'
					&& textCurrent.charAt(start1 + 4) == 'e') {
				System.out.println("��ʼ��while��instruction");
				// System.out.println(new
				// StringBuffer(lireText.substring(pointeurGlobalHead,
				// pointeurGlobalHead+longeurDeWhile(lireText,pointeurGlobalHead))));
				lireInstructionWhile(
						new StringBuffer(lireText.substring(
								pointeurGlobalHead,
								pointeurGlobalHead
										+ longeurDeWhile(lireText,
												pointeurGlobalHead))),
						pointeurGlobalHead
								+ longeurDeWhile(lireText, pointeurGlobalHead));
				// pointeurGlobalHead+=longeurDeWhile(lireText,pointeurGlobalHead);
				System.out.println("����while��instruction");
				// Apr��s avoir fini lecture de instruction if , on na d��j��
				// ��pluch�� le premier niveau de ce block,
				// il nous reste �� lire son fils
				int tryeur = pointeurGlobalHead + 1;
				while (lireText.charAt(tryeur) == ' ') {
					pointeurGlobalHead++;
					tryeur++;
				}
				pointeurGlobalHead += (tryeur - pointeurGlobalHead);
				lireBlock(new StringBuffer(
						lireText.substring(pointeurGlobalHead)));
			}

			// condition 3,dans ce cas, on devoit lire l'instruction
			// "expression" ou probablement
			// on a d��j�� fini de lire ce block.
			else {

				// dans ce cas,on a d��j�� fini de lire ce block;
				if (lireText.substring(pointeurGlobalHead).indexOf(";") == -1) {
					System.out.println("����Program��");
					return;
				}

				// dans ce cas, on va lire l'instruction de forme "Expression".
				System.out.println("��ʼ����һ��instruction");
				lireInstructionExpr(new StringBuffer(
						lireText.substring(pointeurGlobalHead)));// ����������
				// ,longeurDeExpression(lireText,pointeurGlobalHead
				System.out.println("�����һ��instruction");
				System.out.println(pointeurGlobalHead);
				lireBlock(new StringBuffer(
						lireText.substring(pointeurGlobalHead)));
			}
		}

		// Dans ce cas, on a d��j�� fini de lire ce block!
		else {
			System.out.println();
			realText.append("}");
			pointeurGlobalHead++;
		}

	}

	public void lireInvariant(StringBuffer strInvariant) {
		if (pointeurGlobalHead >= lireText.length())
			return;
		inVarVisuel.supremerAllExpression();
		lireResult = strInvariant;
		int modifierEnd = 0;
		System.out.println("����invariant���Ķ�");
		int start = lireResult.lastIndexOf("{");
		int end = lireResult.lastIndexOf("{") + 1;
		while (end < lireResult.indexOf("}")) {
			// si on atteint le point return, l'on invariant est bien vide!
			while (lireResult.charAt(end) == ' ')
				end++;
			if (lireResult.charAt(end) == '}')
				return;

			// TODO �� modifier
			start = end;

			while (lireResult.charAt(end + 1) != ','
					&& lireResult.charAt(end + 1) != '}')
				end++;
			StringBuffer str = new StringBuffer(lireResult.substring(start,
					end + 1));
			System.out.println(str);
			inVarVisuel.listExpr.add(lireExpressionFort(str));

			// pour v��rifier si on a plusieurs expressions dans une invariant
			modifierEnd = lireResult.substring(end).indexOf(",");
			if (modifierEnd < 0)
				end = lireResult.indexOf("}");

			else {
				end = lireResult.substring(end).indexOf(",") + end + 1;
			}
		}
		System.out.println("�Ѿ���invariantװ���ˣ�");
		if (pointeurGlobalHead >= lireText.length())
			return;
	}

	public void lireInstructionExpr(StringBuffer strInstruction) {
		if (pointeurGlobalHead >= lireText.length())
			return;
		lireResult = strInstruction;
		System.out.println();
		realText.append(lireResult.substring(0, lireResult.indexOf(";") + 1));
		// System.out.println(lireResult);
		int i = 0;
		int tail = 0;
		while (lireResult.charAt(i) == ' ')
			i++;

		while (i < lireResult.indexOf(";")) {
			while (lireResult.charAt(i) == ' ')
				i++;
			int start = i;
			int end = i;
			// TODO
			/*
			 * while(lireResult.charAt(end+1)!=';') end++; StringBuffer
			 * strExpr=new StringBuffer(lireResult.substring(start, end+1));
			 * Expression expr=lireExpression(strExpr);
			 */
			while (lireResult.charAt(end + 1) != '='
					&& lireResult.charAt(end + 1) != ' ')
				end++;
			String strHead = lireResult.substring(start, end + 1);
			end = lireResult.indexOf("=") + 1;

			while (lireResult.charAt(end) == ' ')
				end++;
			start = end;

			while (lireResult.charAt(end + 1) != ' '
					&& lireResult.charAt(end + 1) != ';')
				end++;
			StringBuffer strTail = new StringBuffer(lireResult.substring(start,
					end + 1));
			Expression exprTail = lireExpression(strTail);
			i = lireResult.indexOf(";");
			System.out.println("�ѱ��ʽ��ֺ��ˣ�");
			System.out.println(strTail);
			System.out.println(strHead);

			// expression au cas inversible:
			if (lireExpression(strTail).subList.keySet().contains(strHead)
					&& (!lireExpression(strTail).subList.get(strHead).isZero())) { // Ҫ�����Ƿ�Ϊ������
				System.out.println("����ĸ�ֵ����");
				Fraction tailHead = exprTail.subList.get(strHead);
				for (Expression exprTry : inVarReel.listExpr) {
					int note = inVarReel.listExpr.indexOf(exprTry);
					if (exprTry.subList.keySet().contains(strHead)) {
						for (String strNom : inVarReel.listExpr.get(note).subList
								.keySet()) {

							if (strNom.equals(strHead)) // TODO ����������
								inVarReel.listExpr.get(note).subList.put(
										strNom,
										inVarReel.listExpr.get(note).subList
												.get(strNom).multiple(
														(tailHead).signum()));

							else {
								/*
								 * inVarReel.listExpr.get(note).subList.put(strNom
								 * ,
								 * inVarReel.listExpr.get(note).subList.get(strNom
								 * )
								 * Math.abs(exprTail.subList.get(strHead))-(int)
								 * Math.signum(exprTail.subList.get(strHead))
								 * inVarReel
								 * .listExpr.get(note).subList.get(strHead
								 * )*exprTail.subList.get(strNom));
								 */
								inVarReel.listExpr.get(note).subList
										.put(strNom,
												inVarReel.listExpr.get(note).subList
														.get(strNom)
														.multiple(
																tailHead.multiple(tailHead
																		.signum()))
														.soustraire(
																inVarReel.listExpr
																		.get(note).subList
																		.get(strHead)
																		.multiple(
																				exprTail.subList
																						.get(strNom)
																						.multiple(
																								tailHead.signum()))));
							}
						}
					}
				}
			}

			// expression au cas non-inversible:
			else {
				System.out.println("������ĸ�ֵ����");
				LinkedList<Expression> invariantsPositifs = new LinkedList<Expression>();
				LinkedList<Expression> invariantsNegatifs = new LinkedList<Expression>();
				LinkedList<Expression> invariantsNoetre = new LinkedList<Expression>();
				for (Expression exprTry : inVarReel.listExpr) {

					if (!exprTry.subList.keySet().contains(strHead)
							|| exprTry.subList.get(strHead).isZero())
						invariantsNoetre.add(exprTry);

					if (exprTry.subList.get(strHead).strictPositive())
						invariantsPositifs.add(exprTry);

					if (exprTry.subList.get(strHead).strictNegative())
						invariantsNegatifs.add(exprTry);
				}
				Invariant inVarProvisoire = new Invariant(
						new LinkedList<Expression>());

				for (Expression parcoursPositifs : invariantsPositifs) {
					for (Expression parcoursNegatifs : invariantsNegatifs) {
						HashMap<String, Fraction> subListCroise = new HashMap<String, Fraction>();

						Fraction constantCroise = new Fraction(0);
						Fraction nHead = parcoursNegatifs.subList.get(strHead);
						Fraction pHead = parcoursPositifs.subList.get(strHead);

						for (String nom : parcoursPositifs.subList.keySet()) {
							Fraction pNom = parcoursPositifs.subList.get(nom);
							Fraction nNom = parcoursNegatifs.subList.get(nom);
							if (!nom.equals(strHead)) {
								// subListCroise.put(nom,parcoursPositifs.subList.get(nom)
								// *parcoursNegatifs.subList.get(strHead)-parcoursPositifs.subList.get(strHead)
								// *parcoursNegatifs.subList.get(nom));//TODO
								subListCroise.put(nom, pNom.multiple(nHead)
										.soustraire(pHead.multiple(nNom)));
							}
						}
						constantCroise = nHead
								.multiple(parcoursPositifs.constantOfExpression)
								.soustraire(
										pHead.multiple(parcoursNegatifs.constantOfExpression));
						inVarProvisoire.ajouterExpression(new Expression(
								subListCroise, constantCroise));
						// constantCroise=parcoursNegatifs.subList.get(strHead)*parcoursPositifs.constantOfExpression
						// -parcoursPositifs.subList.get(strHead)*parcoursNegatifs.constantOfExpression;
						// inVarProvisoire.ajouterExpression(new
						// Expression(subListCroise,constantCroise));
					}
				}
			}
		}
		System.out.println("expressionȫ����װ��ϣ�");
		pointeurGlobalHead += i + 1;
		if (pointeurGlobalHead >= lireText.length())
			return;
	}

	public void lireInstructionIf(StringBuffer strInstruction, int pointDeArret) {
		if (pointeurGlobalHead >= lireText.length())
			return;
		lireResult = strInstruction;
		int i = 0, mesure = 0;
		int startIf = 0, endIf = 0, startElse = 0, endElse = 0;
		while (lireResult.charAt(i) == ' ')
			i++;

		if (lireResult.charAt(i) == 'i' && lireResult.charAt(i + 1) == 'f') {

			// m��thode pour enregistrer la condition de if:
			i = lireResult.indexOf("(") + 1;
			System.out.println(i);
			while (lireResult.charAt(i) == ' ')
				i++;
			int start = i;
			int end = i;
			// TODO
			while (lireResult.charAt(end + 1) != ')')
				end++;
			StringBuffer strCondition = new StringBuffer(lireResult.substring(
					start, end + 1));

			// m��thode pour calculer la port�� de if:
			LinkedList<String> marqueur = new LinkedList<String>();
			int point = end;
			System.out.println(point);
			startIf = lireResult.indexOf(")");
			while (lireResult.charAt(startIf) != '{')
				startIf++;
			System.out.println();
			realText.append(lireResult.substring(0, startIf + 1));
			marqueur.add("{");
			point = startIf;
			pointeurGlobalHead += startIf + 1;// ƽ��һ����λ��

			while (!marqueur.isEmpty()) {
				point++;
				if (lireResult.substring(point).charAt(0) == '{')
					marqueur.push("{");
				if (lireResult.substring(point).charAt(0) == '}')
					marqueur.poll();
			}
			endIf = point;

			startElse = point;

			while (lireResult.substring(startElse).charAt(0) != '{')
				startElse++;
			marqueur.add("{");
			point = startElse;
			while (!marqueur.isEmpty()) {
				point++;
				if (lireResult.substring(point).charAt(0) == '{')
					marqueur.push("{");
				if (lireResult.substring(point).charAt(0) == '}')
					marqueur.poll();
			}
			endElse = point;
			StringBuffer strInstructionIf = new StringBuffer(
					lireResult.substring(startIf + 1, endIf));// ���������ָ��ṹ
			StringBuffer strInstructionElse = new StringBuffer(
					lireResult.substring(startElse + 1, endElse));
			// System.out.println(strInstructionIf);
			// System.out.println(strInstructionElse);
			Invariant marqueurInvariant = inVarReel;
			// System.out.println(strCondition);

			// on commence �� lire petit block if:
			inVarReel.ajouterExpression(lireExpressionFort(strCondition));
			System.out.println("����if����");
			System.out.println(strInstructionIf);
			lireBlock(strInstructionIf);
			System.out.println("����if��block");
			inVarReel = marqueurInvariant;
			// }
			// if(!lireCondition(strCondition)){

			// on commence a lire petit block else��
			System.out.println(pointeurGlobalHead);
			System.out.println("��ʼ��else��������");
			System.out.println(lireText.charAt(pointeurGlobalHead));
			realText.append("else{");
			System.out.println();

			// m��thode pour traduire la condition de while:
			HashMap<String, Fraction> subListPro = new HashMap<String, Fraction>();
			Fraction constantPro = new Fraction(0);
			for (String nom : lireExpressionFort(strCondition).subList.keySet()) {
				subListPro.put(nom, lireExpressionFort(strCondition).subList
						.get(nom).multiple(-1));
			}
			constantPro = lireExpressionFort(strCondition).constantOfExpression
					.multiple(-1).soustraire(1);// TODO
			inVarReel
					.ajouterExpression(new Expression(subListPro, constantPro));
			System.out.println("��ʼ��else��block");
			pointeurGlobalHead += lireText.substring(pointeurGlobalHead)
					.indexOf("{") + 1;
			System.out.println(pointeurGlobalHead);
			lireBlock(strInstructionElse);
			System.out.println("����else��block");
			inVarReel = marqueurInvariant;
			// }
		}
		System.out.println("Bonjour");
		System.out.println(pointeurGlobalHead);
		if (pointeurGlobalHead >= lireText.length())
			return;
	}

	public void lireInstructionWhile(StringBuffer strInstruction,
			int pointDeDepart) {
		if (pointeurGlobalHead >= lireText.length())
			return;
		lireResult = strInstruction;
		int i = 0;
		while (lireResult.charAt(i) == ' ')
			i++;
		if (lireResult.charAt(i) == 'w' && lireResult.charAt(i + 1) == 'h'
				&& lireResult.charAt(i + 2) == 'i'
				&& lireResult.charAt(i + 3) == 'l'
				&& lireResult.charAt(i + 4) == 'e') {
			i = lireResult.indexOf("(") + 1;
			while (lireResult.charAt(i) == ' ')
				i++;
			int start = i;
			int end = i;
			// TODO
			while (lireResult.charAt(end + 1) != ')')
				end++;
			StringBuffer strCondition = new StringBuffer(lireResult.substring(
					start, end + 1));
			int startIf = lireResult.indexOf(")");

			while (lireResult.charAt(startIf) != '{')
				startIf++;
			int point = end + 1;
			int startWhile = point;
			while (lireResult.charAt(startWhile) != '{')
				startWhile++;
			realText.append(lireResult.substring(0, startWhile + 1));
			System.out.println();
			LinkedList<String> marqueur = new LinkedList<String>();
			marqueur.add("{");
			point = startWhile;
			pointeurGlobalHead += startWhile + 1;
			System.out.println(startWhile);
			while (!marqueur.isEmpty()) {
				point++;
				if (lireResult.substring(point).charAt(0) == '{')
					marqueur.push("{");
				if (lireResult.substring(point).charAt(0) == '}')
					marqueur.poll();
			}
			int endWhile = point;
			i = endWhile;
			StringBuffer strInstructionWhile = new StringBuffer(
					lireResult.substring(startWhile + 1, endWhile + 1));
			System.out.println(strInstructionWhile);
			inVarReel.ajouterExpression(lireExpressionFort(strCondition));
			lireBlock(strInstructionWhile);
		}
	}

	public Expression lireExpressionFort(StringBuffer strBuf) {
		StringBuffer inegalite = strBuf;
		LinkedList<String> subStr = new LinkedList<String>();
		Expression expr = new Expression(new HashMap<String, Fraction>(),
				new Fraction(0));
		if (inegalite.indexOf(">") == -1 && inegalite.indexOf("<") == -1) {
			return lireExpression(inegalite);
		} else {
			if (inegalite.indexOf(">=") != -1) {
				int i = 0;
				while (inegalite.charAt(i) == ' ')
					i++;
				int startGauche = i;
				String strGauche = inegalite.substring(startGauche,
						inegalite.indexOf(">="));
				String strDroite = inegalite
						.substring(inegalite.indexOf("=") + 1);
				Expression exprGauche = lireExpression(new StringBuffer(
						strGauche));
				Expression exprDroite = lireExpression(new StringBuffer(
						strDroite));
				Expression exprReal = new Expression(
						new HashMap<String, Fraction>(), new Fraction(0));
				for (String nom : list.keySet()) {
					Fraction valueReal = exprGauche.subList.get(nom)
							.soustraire(exprDroite.subList.get(nom));
					exprReal.subList.put(nom, valueReal);
				}
				exprReal.constantOfExpression = exprGauche.constantOfExpression
						.soustraire(exprDroite.constantOfExpression);
				return exprReal;
			}

			else if (inegalite.indexOf(">") != -1) {
				int i = 0;
				while (inegalite.charAt(i) == ' ')
					i++;
				int startGauche = i;
				String strGauche = inegalite.substring(startGauche,
						inegalite.indexOf(">"));
				String strDroite = inegalite
						.substring(inegalite.indexOf(">") + 1);
				Expression exprGauche = lireExpression(new StringBuffer(
						strGauche));
				Expression exprDroite = lireExpression(new StringBuffer(
						strDroite));
				Expression exprReal = new Expression(
						new HashMap<String, Fraction>(), new Fraction(0));
				for (String nom : list.keySet()) {
					Fraction valueReal = exprGauche.subList.get(nom)
							.soustraire(exprDroite.subList.get(nom));
					exprReal.subList.put(nom, valueReal);
				}
				exprReal.constantOfExpression = exprGauche.constantOfExpression
						.soustraire(exprDroite.constantOfExpression)
						.soustraire(1);
				return exprReal;
			}

			if (inegalite.indexOf("<=") != -1) {
				int i = 0;
				while (inegalite.charAt(i) == ' ')
					i++;
				int startGauche = i;
				String strGauche = inegalite.substring(startGauche,
						inegalite.indexOf("<="));
				String strDroite = inegalite
						.substring(inegalite.indexOf("=") + 1);
				Expression exprGauche = lireExpression(new StringBuffer(
						strGauche));
				Expression exprDroite = lireExpression(new StringBuffer(
						strDroite));
				Expression exprReal = new Expression();
				// TODO
				for (String nom : list.keySet()) {
					Fraction valueReal = exprDroite.subList.get(nom)
							.soustraire(exprGauche.subList.get(nom));
					exprReal.subList.put(nom, valueReal);
				}
				exprReal.constantOfExpression = exprDroite.constantOfExpression
						.soustraire(exprGauche.constantOfExpression);
				return exprReal;
			}

			else if (inegalite.indexOf("<") != -1) {
				int i = 0;
				while (inegalite.charAt(i) == ' ')
					i++;
				int startGauche = i;
				String strGauche = inegalite.substring(startGauche,
						inegalite.indexOf("<"));
				String strDroite = inegalite
						.substring(inegalite.indexOf("<") + 1);
				Expression exprGauche = lireExpression(new StringBuffer(
						strGauche));
				Expression exprDroite = lireExpression(new StringBuffer(
						strDroite));
				Expression exprReal = new Expression();
				for (String nom : list.keySet()) {
					Fraction valueReal = exprDroite.subList.get(nom)
							.soustraire(exprGauche.subList.get(nom));
					exprReal.subList.put(nom, valueReal);
				}
				exprReal.constantOfExpression = exprDroite.constantOfExpression
						.soustraire(exprGauche.constantOfExpression)
						.soustraire(1);
				return exprReal;
			}
		}
		return null;
	}

	public Expression lireExpression(StringBuffer strBuf) {
		// if(pointeurGlobalHead>=lireText.length()) return null;
		System.out.println("����lireExpression");
		StringBuffer sB = strBuf;
		// System.out.println(sB);
		StringBuffer nB = new StringBuffer();
		// System.out.println(sB);
		LinkedList<String> subStr = new LinkedList<String>();
		Expression expr = new Expression();
		for (String nom : list.keySet()) {
			expr.subList.put(nom, new Fraction(0));
		}
		int i = 0, test = 0;
		int start = 0;
		int end = 0;
		for (int m = 0; m < sB.length(); m++) {
			if (sB.charAt(m) != ' ')
				nB.append(sB.charAt(m));
		}
		System.out.println(nB);
		if (nB.charAt(test) == '{') {
			if (nB.length() == 2) {
				HashMap<String, Fraction> subList = new HashMap<String, Fraction>();
				for (String nom : list.keySet()) {
					subList.put(nom, new Fraction(0));
				}
				return new Expression(subList, new Fraction(0));
			}
			nB = new StringBuffer(sB.substring(test + 1, sB.indexOf("}")));// �����Ƿ������һ��"}"
		}
		while (i < nB.length()) {
			// TODO ���������⣡����
			start = i;
			end = i;

			if ((nB.indexOf("+") == -1) && (nB.indexOf("-") == -1)) {
				System.out.println("����������");
				subStr.add(nB.substring(start));
				i = nB.length();
			} else {
				System.out.println("�����������");
				while ((nB.charAt(end + 1) != '+')
						&& (nB.charAt(end + 1) != '-') && end < nB.length() - 2)
					end++;
				if (end < nB.length() - 2) {
					subStr.add(nB.substring(start, end + 1));
					start = end + 1;
					i = start;
				} else {
					subStr.add(nB.substring(start, nB.length()));
					i = nB.length();
				}
			}// TODO �������ڣ�
			if (pointeurGlobalHead >= lireText.length())
				return null;
		}

		System.out.println("�Ӽ���������");
		for (String subString : subStr) {
			System.out.println(subString);
			// for(int j=0;j<subString.length();j++){
			int note = 0;

			if (subString.charAt(note) != '-') {
				if (subString.charAt(note) == '+')
					note++;
				int start1 = note;
				int end1 = note;
				if (subString.indexOf("*") == -1) {
					if (list.containsKey(subString.substring(start1,
							subString.length()))) {
						expr.subList
								.put(subString.substring(start1,
										subString.length()),
										expr.subList.get(
												subString.substring(start1,
														subString.length()))
												.plus(1));
					}

					else {
						int n = Integer.parseInt(subString.substring(start1,
								subString.length()));
						expr.constantOfExpression = expr.constantOfExpression
								.plus(n);
					}
				}

				else {
					String facteurGauche = subString.substring(start1,
							subString.indexOf("*"));
					String facteurDroite = subString.substring(
							subString.indexOf("*") + 1, subString.length());
					if (list.containsKey(facteurGauche)) {
						expr.subList.put(
								facteurGauche,
								expr.subList.get(facteurGauche).plus(
										Integer.parseInt(facteurDroite)));
					}
					if (list.containsKey(facteurDroite)) {
						expr.subList.put(
								facteurDroite,
								expr.subList.get(facteurDroite).plus(
										Integer.parseInt(facteurGauche)));
					} else {
						int n = Integer.parseInt(facteurGauche)
								* Integer.parseInt(facteurDroite);
						expr.constantOfExpression = expr.constantOfExpression
								.plus(n);
					}
				}
			}

			if (subString.charAt(note) == '-') {
				System.out.println("���ϵ��Ϊ��");
				note++;
				int start1 = note;
				int end1 = note;
				if (subString.indexOf("*") == -1) {
					if (list.containsKey(subString.substring(start1,
							subString.length()))) {
						expr.subList
								.put(subString.substring(start1,
										subString.length()),
										expr.subList.get(
												subString.substring(start1,
														subString.length()))
												.soustraire(1));
					}

					else {
						int n = Integer.parseInt(subString.substring(start1,
								subString.length()));
						expr.constantOfExpression = expr.constantOfExpression
								.soustraire(n);
					}
				}

				else {
					String facteurGauche = subString.substring(start1,
							subString.indexOf("*"));
					String facteurDroite = subString.substring(
							subString.indexOf("*") + 1, subString.length());
					if (list.containsKey(facteurGauche)) {
						expr.subList.put(
								facteurGauche,
								expr.subList.get(facteurGauche).soustraire(
										Integer.parseInt(facteurDroite)));
					}
					if (list.containsKey(facteurDroite)) {
						expr.subList.put(
								facteurDroite,
								expr.subList.get(facteurDroite).soustraire(
										Integer.parseInt(facteurGauche)));
					} else {
						int n = Integer.parseInt(facteurGauche)
								* Integer.parseInt(facteurDroite);
						expr.constantOfExpression = expr.constantOfExpression
								.soustraire(n);
					}
				}
			}
		}
		return expr;
	}

	public boolean lireCondition(StringBuffer strBuffer) {
		if (!valueOfExpression(lireExpressionFort(strBuffer)).strictNegative())
			return true;
		return false;
	}

	public Fraction valueOfExpression(Expression expr) {
		Fraction value = new Fraction(0);
		for (String nom : expr.subList.keySet()) {
			value = value.plus(list.get(nom).multiple(expr.subList.get(nom)));
		}
		value = value.plus(expr.constantOfExpression);
		return value;
	}

	public int longeurDeIf(StringBuffer textLu, int depart) {
		LinkedList<String> marqueurLocal = new LinkedList<String>();
		int i = depart;
		while (textLu.charAt(i) != '{')
			i++;
		marqueurLocal.add("{");

		while (!marqueurLocal.isEmpty()) {
			i++;
			if (textLu.charAt(i) == '{')
				marqueurLocal.push("{");
			if (textLu.charAt(i) == '}')
				marqueurLocal.poll();
		}
		i++;
		while (textLu.charAt(i) != '{')
			i++;
		marqueurLocal.add("{");

		while (!marqueurLocal.isEmpty()) {
			i++;
			if (textLu.charAt(i) == '{')
				marqueurLocal.push("{");
			if (textLu.charAt(i) == '}')
				marqueurLocal.poll();
		}
		return i - depart + 1;
	}

	public int longeurDeWhile(StringBuffer textLu, int depart) {
		LinkedList<String> marqueurLocal = new LinkedList<String>();
		int i = depart;
		while (textLu.charAt(i) != '{')
			i++;
		marqueurLocal.add("{");
		while (!marqueurLocal.isEmpty()) {
			i++;
			if (textLu.charAt(i) == '{')
				marqueurLocal.push("{");
			if (textLu.charAt(i) == '}')
				marqueurLocal.poll();
		}
		return i - depart + 1;
	}

	public int longeurDeExpression(StringBuffer textLu, int depart) {
		return textLu.substring(depart).indexOf(";") + 1;
	}

	public void lirePragram() {
		lireDeclaration();
		String s = data.nextData();
		while (s != null) {
			lireResult = new StringBuffer(s);
			lireText.append(lireResult);
			s = data.nextData();
		}
		// System.out.println(lireText);
		lireBlock(new StringBuffer(lireText.substring(pointeurGlobalHead)));
		// System.out.println(realText);
		System.out.println("��ɶ�д��������");
	}
	
	
	
	
	//////////////////////////////////////
	//TODO
	public boolean isRight() {
		Verification veri=new Verification(SetVar);
		return veri.isIncludedIn(inVarVisuel,inVarReel);
	}
	public void simpInv(Invariant inv){
		Verification veri=new Verification(SetVar);
		
	}
/////////////////////////////////////////////////
	
	public static void main(String[] args) {
		String datafile = "E:/d.txt";
		Program program = new Program(datafile);
		program.lirePragram();
	}
}
